﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace AIC_Notification
{
    public class AIC_List
    {
        public string ListName { get; set; }
        public string ListId { get; set; }
        public string Note { get; set; }

        public AIC_List()
        {
        }

        public virtual void CalculateStatistics()
        {
        }
    }

    public class Guidance_MonthlyPlanList : AIC_List
    {
        public IList<Guidance_MonthlyPlan> MonthlyPlanList = null;

        public Guidance_MonthlyPlanList(string Id)
        {
            ListName = "";
            ListId = Id;
            Note = "";
            MonthlyPlanList = new List<Guidance_MonthlyPlan>();
        }

        public void SetList(string listName)
        {
            // Record Trello Information 
            ListName = listName;
            Note = "";
        }

    }

    public class Guidance_MeetingRecapList : AIC_List
    {
        public IList<Guidance_MeetingRecap> MeetingRecapList = null;

        public Guidance_MeetingRecapList(string Id)
        {
            ListName = "";
            ListId = Id;
            Note = "";
            MeetingRecapList = new List<Guidance_MeetingRecap>();
        }

        public void SetList(string listName)
        {
            // Record Trello Information 
            ListName = listName;
            Note = "";
        }

    }

    public class Guidance_EvaluationReportCardList : AIC_List
    {
        public IList<Guidance_ReportCard> ReportCards = null;

        public Guidance_EvaluationReportCardList(string Id)
        {
            ListName = "";
            ListId = Id;
            Note = "";
            ReportCards = new List<Guidance_ReportCard>();
        }

        public void SetList(string listName)
        {
            // Record Trello Information 
            ListName = listName;
            Note = "";
        }

    }

    public class SOF_WorkList : AIC_List
    {
        public enum ApplicationSchoolType { None, Early1, Early2 };

        public string ListType { get; set; }
        public string School { get; set; }
        public SchoolAdmissionStatistics.SchoolListType SchoolType = SchoolAdmissionStatistics.SchoolListType.Unknown;
        public int Rally { get; set; }
        public ApplicationSchoolType ApplicationType = ApplicationSchoolType.None;
        public bool NonSuppliment = false;
        public IList<Essay> Essays;
        public IList<Task> Tasks;
        public int TotalLateEssay;

        [JsonIgnore]
        public SchoolStatistics SchoolStats;
        [JsonIgnore]
        public School SchoolObject = null;

        public SOF_WorkList(string Id)
        {
            ListName = "";
            ListId = Id;
            ListType = "";
            School = "";
            Rally = -1;
            Note = "";
            SchoolStats = new SchoolStatistics();
            TotalLateEssay = 0;
        }

        public void SetList(string listName, string type, string school, int rally, ApplicationSchoolType Type = ApplicationSchoolType.None, bool IsNS = false)
        {
            // Record Trello Information 
            ListName = listName;
            Note = "";

            ListType = type;
            School = school;
            Rally = rally;
            ApplicationType = Type;
            NonSuppliment = IsNS;

            Essays = new List<Essay>();
            Tasks = new List<Task>();

            if (ListType == "School")
            {
                string ApplicationTypeString = "Normal";

                if (ApplicationType == ApplicationSchoolType.Early1)
                {
                    ApplicationTypeString = "Early Application";
                }
                else if (ApplicationType == ApplicationSchoolType.Early2)
                {
                    ApplicationTypeString = "Early Application 2";
                }

                Global.SysUtil.Log(String.Format("School: {0} (Rally {1}, {2}{3})", School, Rally, ApplicationTypeString, NonSuppliment ? "-NS" : ""));
            }
            else
                Global.SysUtil.Log(String.Format("Work List: {0} {1}", ListType, (rally != -1) ? ("(Rally " + rally + ")") : ""));
        }

        public override void CalculateStatistics()
        {
            const int LATE_BY_LIMIT = 1;

            SchoolStats = new SchoolStatistics();
            SchoolStats.AllEssayGoalMet = true;
            int RallyRed = 0, RallyYellow = 0, RallyGreen = 0;

            // Calculate Statistics for each card
            foreach (var Essay in Essays)
            {
                Essay.CalculateStatistics();

                // Calculate Number of Late Essay
                if (Essay.hasDueDate)
                {
                    TimeSpan LateEssay = Essay.hasDraftAttachment ?
                                         Essay.DraftAttachmentDate - Essay.DueDate :
                                         Global.Now() - Essay.DueDate;

                    if (LateEssay.Days > LATE_BY_LIMIT)
                    {
                        SchoolStats.NumberOfLateEssay += 1;
                    }
                }
            }

            // Figure out how many essay in this school list
            int NumberOfEssay = 0;
            foreach (var essay in Essays)
            {
                if (essay.Number > NumberOfEssay)
                    NumberOfEssay = essay.Number;
            }
            SchoolStats.NumberOfEssay = NumberOfEssay;

            // Figure out lastest draft for each essay
            // Find most recent draft for each essay and other info
            for (int i = 1; i <= NumberOfEssay; i++)
            {
                int MostRecentDraft;
                EssayStatistics NewEssayStats = new EssayStatistics();
                NewEssayStats.EssayNumber = i;

                // Find most recent draft for this essay
                Essay mostRecentEssay = null;
                Essay mostRecentPendingEssay = null;
                MostRecentDraft = -50;
                foreach (var essay in Essays)
                {
                    int EssayNumber;

                    // Find most recent card with draft
                    if (essay.Number == i)
                    {
                        EssayNumber = essay.BrainStorm ? essay.DraftNumber - 50 : essay.DraftNumber; // Assume no more than 50 BSs

                        if (EssayNumber > MostRecentDraft)
                        {
                            if (essay.hasRevision || essay.isFinal || essay.hasDraftAttachment)
                            {
                                MostRecentDraft = EssayNumber;
                                mostRecentEssay = essay;
                            }
                            else
                            {
                                mostRecentPendingEssay = essay;
                            }
                        }
                    }
                }
                NewEssayStats.LatestDraft = MostRecentDraft == -50 ? 0 : MostRecentDraft;

                // Current Rally Status
                if (mostRecentEssay != null)
                {
                    if (School == "CEF")
                        NewEssayStats.RallyStatus = RallyHelper.RallyStatus(Rally, School, i, NewEssayStats.LatestDraft);
                    else
                        NewEssayStats.RallyStatus = mostRecentEssay.isFinal != true ? RallyHelper.RallyStatus(Rally, School, i, NewEssayStats.LatestDraft) : 1;

                    if (NewEssayStats.RallyStatus == 1)
                        RallyGreen += 1;
                    else if (NewEssayStats.RallyStatus == 2)
                        RallyYellow += 1;
                    else if (NewEssayStats.RallyStatus == 3)
                        RallyRed += 1;
                }

                // Met Rally Goal
                NewEssayStats.MetRallyGoal = RallyHelper.RallyGoalComplete(Rally, School, i, NewEssayStats.LatestDraft);

                if (mostRecentPendingEssay != null)
                {
                    NewEssayStats.PendingDraftObject = mostRecentPendingEssay;

                    // Check if Missing DueDate
                    if (!mostRecentPendingEssay.hasDraftAttachment &&
                        !mostRecentPendingEssay.hasRevisionAttachment &&
                        !mostRecentPendingEssay.hasDueDate)
                    {
                        NewEssayStats.HasIssue = true;
                        NewEssayStats.MissingDueDate = true;
                        mostRecentPendingEssay.Note += "Add Due Date";
                    }

                    // Has overdued draft from student?
                    if ((!mostRecentPendingEssay.hasDraftAttachment) &&    // No Draft Attachment
                    (!mostRecentPendingEssay.hasRevision) &&           // Not marked Revision
                    (mostRecentPendingEssay.hasDueDate))            // Has Due Date
                    {
                        NewEssayStats.HasIssue = true;
                        //if (Global.Now() > mostRecentPendingEssay.DueDate)
                        NewEssayStats.HasOverDuedDraft = true;
                    }
                    else
                        NewEssayStats.HasOverDuedDraft = false;
                }

                // If the essay has any draft...  
                if (mostRecentEssay != null)
                {
                    NewEssayStats.DraftObject = mostRecentEssay;

                    // Any draft pending revision from teacher?
                    if (mostRecentEssay.hasDraftAttachment && (!mostRecentEssay.hasRevision) && (!mostRecentEssay.isFinal)) // Has draft but neither has revision nor marked final
                    {
                        NewEssayStats.HasIssue = true;
                        NewEssayStats.HasRevisionPending = true;
                        NewEssayStats.DraftAttachmentDate = mostRecentEssay.DraftAttachmentDate;
                        NewEssayStats.PendingTimeSpan = Global.SysUtil.WorkingDaysBetween(mostRecentEssay.DraftAttachmentDate, Global.Now());
                    }

                    // Check if Revision Marked but No Attachment
                    if (mostRecentEssay.hasRevision || mostRecentEssay.isFinal)
                    {
                        if (!mostRecentEssay.hasDraftAttachment && !mostRecentEssay.hasRevisionAttachment)
                        {
                            NewEssayStats.HasIssue = true;
                            NewEssayStats.MissingAttachment = true;
                            mostRecentEssay.Note += "Need Attachment;";
                        }
                    }

                    // Check if people forgot to mark final
                    TimeSpan IdleTimeSpan;
                    if ((!mostRecentEssay.isFinal))
                    {
                        if ((mostRecentEssay.hasRevision) && (mostRecentEssay.hasRevisionAttachment && mostRecentEssay.RevisionAttachmentName != null))
                        {
                            IdleTimeSpan = Global.Now() - mostRecentEssay.RevisionAttachmentDate;
                            if (IdleTimeSpan.TotalDays > 30)
                            {
                                NewEssayStats.HasIssue = true;
                                NewEssayStats.MissingFinalTag = true;
                                mostRecentEssay.Note += "Forgot final tag /F?";
                            }
                        }
                        else
                        {
                            if ((mostRecentEssay.hasDraftAttachment) && (mostRecentEssay.hasDraftAttachment && mostRecentEssay.DraftAttachmentName != null))
                            {
                                IdleTimeSpan = Global.Now() - mostRecentEssay.DraftAttachmentDate;
                                if (IdleTimeSpan.TotalDays > 30)
                                {
                                    NewEssayStats.HasIssue = true;
                                    NewEssayStats.MissingFinalTag = true;
                                    mostRecentEssay.Note = "Forgot final tag /F?";
                                }
                            }
                        }
                    }

                    // Check if this essay is done
                    SchoolStats.AllEssayGoalMet &= (NewEssayStats.MetRallyGoal || mostRecentEssay.isFinal);

                } // mostRecentEssay

                SchoolStats.EssayStatisticsList.Add(NewEssayStats);

                // Calculate Rally Status for Card
                if (RallyRed > 0 && RallyYellow == 0 && RallyGreen == 0)
                    SchoolStats.RallyStatus = 3;
                else if (RallyRed == 0 && RallyYellow > 0 && RallyGreen == 0)
                    SchoolStats.RallyStatus = 2;
                else if (RallyRed == 0 && RallyYellow == 0 && RallyGreen > 0)
                    SchoolStats.RallyStatus = 1;
                else if (RallyRed == 0 && RallyYellow == 0 && RallyGreen == 0)
                {
                    if (Rally > 0 && Rally <= RallyHelper.CurrentRally) // Rally > 0 but within Current Rally
                        SchoolStats.RallyStatus = 3;
                    else
                        SchoolStats.RallyStatus = 0;
                }
                else
                    SchoolStats.RallyStatus = 4; // Mixed
            }
        }
    }
}
